package com.gitee.wsl.platform.thread.task.api

import com.gitee.wsl.platform.thread.task.bean.ExitCase
import com.gitee.wsl.platform.thread.task.bean.Task
import java.lang.AutoCloseable
import java.util.function.Function

/**
 * Blocking/synchronous finalizer of [Resource].
 *
 * @see Resource.fromBlockingIO
 */
@FunctionalInterface
fun interface CloseableFun : AutoCloseable {
    @Throws(Exception::class)
    fun close(exitCase: ExitCase)

    /**
     * Converts this blocking finalizer into an asynchronous one
     * that can be used for initializing [Resource.Acquired].
     */
    fun toAsync(): Function<ExitCase, Task<Void?>> {
        return Function { exitCase: ExitCase ->
            DelayedFun{
                close(exitCase)
                null
            }.taskUninterruptibleBlockingIO()
        }
    }

    @Throws(Exception::class)
    override fun close() {
        close(ExitCase.succeeded())
    }

    companion object {
        fun fromAutoCloseable(resource: AutoCloseable): CloseableFun {
            return CloseableFun { ignored: ExitCase -> resource.close() }
        }

        /**
         * Reusable reference for a no-op `CloseableFun`.
         */
        val NOOP: CloseableFun = CloseableFun { ignored: ExitCase -> }
    }
}
